package com.pan.thread;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * 实现callable接口的类
 * @author by panstark
 * @description
 * @notice
 * @date 2021/4/29
 */
@Slf4j
public class HorseCallable implements Callable {
    @Override
    public Object call() throws Exception {
        log.info("我实现了callable接口，是一匹回调马，当前线程是:{}",Thread.currentThread().getName());
        Thread.sleep(3000);
        return "神奇的回调,线程是："+Thread.currentThread().getName();
    }

    /**
     * 注意此用例中始终只有main线程一个人在跑,业界劳模
     * FutureTask.run并不会创建一个新线程
     * start才会创建一个新线程
     */
    public void runByMySelf(){

        FutureTask horseTask1 = new FutureTask(new HorseCallable());
        log.info("horseTask1开始跑了。");
        horseTask1.run();
        FutureTask horseTask2 = new FutureTask(new HorseCallable());
        log.info("horseTask2开始跑了。");
        horseTask2.run();
        try {
            Object horseTask1Call = horseTask1.get();
            log.info("线程{}在等待，horseTask1Call:{}",Thread.currentThread().getName(),horseTask1Call);
            Object horseTask2Call = horseTask2.get();
            log.info("线程{}在等待，horseTask2Call:{}",Thread.currentThread().getName(),horseTask2Call);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    /**
     * 手动创建两个线程运行方法
     */
    public void runByNewThread(){

        FutureTask horseTask1 = new FutureTask(new HorseCallable());
        log.info("horseTask1开始跑了。");

        Thread horseThread1 = new Thread(horseTask1);
        horseThread1.setName("回调马1");
        horseThread1.start();

        FutureTask horseTask2 = new FutureTask(new HorseCallable());
        log.info("horseTask2开始跑了。");
        Thread horseThread2 = new Thread(horseTask2);
        horseThread2.setName("回调马2");
        horseThread2.start();

        try {
            //获取callback的执行内容
            Object horseTask1Call = horseTask1.get();
            log.info("线程{}在等待，horseTask1Call:{}",Thread.currentThread().getName(),horseTask1Call);
            Object horseTask2Call = horseTask2.get();
            log.info("线程{}在等待，horseTask2Call:{}",Thread.currentThread().getName(),horseTask2Call);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        HorseCallable horseCallable = new HorseCallable();
        horseCallable.runByMySelf();
        horseCallable.runByNewThread();

        log.info("线程:{}跑完了。",Thread.currentThread().getName());
    }
}
